#include "diagramaffectdeaddialog.h"

#include "histogram_item.h"
#include <QPen>
#include <QColor>
#include "qwt/include/qwt_plot.h"
#include "qwt/include/qwt_plot_item.h"
#include "qwt/include/qwt_interval_data.h"
#include "logic.h"

#include <QLabel>
#include <QComboBox>
#include <QDateEdit>
#include <QLineEdit>
#include <QDoubleSpinBox>
#include <QLayout>
#include <QPushButton>
#include <QDialogButtonBox>
#include <QMessageBox>
#include <QDateEdit>

int daysInMonth(int y, int m) {
    return (m!=2?((m%2)^(m>7))+30:(!(y%400)||(!(y%4)&&(y%25))?29:28));
}

DiagramAffectDeadDialog::DiagramAffectDeadDialog(QWidget *parent)
    : QDialog(parent)
{
    //all
    vblMain = new QVBoxLayout;

    hblTop = new QHBoxLayout;

    lbLocation = new QLabel(tr("Нас пункт:"));
    hblTop->addWidget(lbLocation);
    cbLocation = new QComboBox;
    cbLocation->addItems(logic::getLocations());
    hblTop->addWidget(cbLocation);
    deDate = new QDateEdit();
    deDate->setCalendarPopup(true);
    deDate->setDate(QDate::currentDate());
    hblTop->addWidget(deDate);

    lbPeriod = new QLabel(tr("Период:"));
    hblTop->addWidget(lbPeriod);
    cbPeriod = new QComboBox;
    cbPeriod->addItem(tr("Месяц"));
    cbPeriod->addItem(tr("Год"));
    hblTop->addWidget(cbPeriod);

    lbNumBegin = new QLabel(tr("Номера ДТП:"));
    hblTop->addWidget(lbNumBegin);
    sbNumBegin = new QSpinBox;
    hblTop->addWidget(sbNumBegin);
    sbNumEnd = new QSpinBox;
    hblTop->addWidget(sbNumEnd);

    vblMain->addLayout(hblTop);

    swBase = new QStackedWidget;
    connect(cbLocation, SIGNAL(activated(int)),
            swBase, SLOT(setCurrentIndex(int)));

    //Stav
    wStav = new QWidget;
    hblBaseStav = new QHBoxLayout;

    lbDistrict = new QLabel(tr("Район:"));
    hblBaseStav->addWidget(lbDistrict);
    cbDistrict = new QComboBox;
    cbDistrict->addItems(logic::getDistricts());
    cbDistrict->setCurrentIndex(-1);
    hblBaseStav->addWidget(cbDistrict);

    lbStreet1 = new QLabel(tr("Улица:"));
    hblBaseStav->addWidget(lbStreet1);
    cbStreet1 = new QComboBox;
    cbStreet1->addItems(logic::getSreets());
    cbStreet1->setCurrentIndex(-1);
    hblBaseStav->addWidget(cbStreet1);

    chbCrossroadStav = new QCheckBox;
    chbCrossroadStav->setText(tr("Перекресток"));
    hblBaseStav->addWidget(chbCrossroadStav);

    connect(chbCrossroadStav, SIGNAL(clicked()),
            this, SLOT(on_chbCrossroadStav_clicked()));
    //on_chbCrossroadStav_clicked();

    lbStreet2 = new QLabel(tr("Улица 2:"));
    hblBaseStav->addWidget(lbStreet2);
    cbStreet2 = new QComboBox;
    cbStreet2->addItems(logic::getSreets());
    cbStreet2->setCurrentIndex(-1);
    hblBaseStav->addWidget(cbStreet2);

    lbHouse = new QLabel(tr("Дом:"));
    hblBaseStav->addWidget(lbHouse);
    leHouse = new QLineEdit;
    hblBaseStav->addWidget(leHouse);
    lbCorps = new QLabel(tr("Корпус:"));
    hblBaseStav->addWidget(lbCorps);
    leCorps = new QLineEdit;
    hblBaseStav->addWidget(leCorps);

    wStav->setLayout(hblBaseStav);
    swBase->addWidget(wStav);

    //Shpa
    wShpa =  new QWidget;
    hblBaseShpa = new QHBoxLayout;

    lbRoad1 = new QLabel(tr("Дорога:"));
    hblBaseShpa->addWidget(lbRoad1);
    cbRoad1 = new QComboBox;
    cbRoad1->addItems(logic::getRoads());
    cbRoad1->setCurrentIndex(-1);
    hblBaseShpa->addWidget(cbRoad1);

    chbCrossroadShpa = new QCheckBox;
    chbCrossroadShpa->setText(tr("Перекресток"));
    hblBaseShpa->addWidget(chbCrossroadShpa);

    connect(chbCrossroadShpa, SIGNAL(clicked()),
            this, SLOT(on_chbCrossroadShpa_clicked()));
    //on_chbCrossroadShpa_clicked();

    lbRoad2 = new QLabel(tr("Дорога 2:"));
    hblBaseShpa->addWidget(lbRoad2);
    cbRoad2 = new QComboBox;
    cbRoad2->addItems(logic::getRoads());
    cbRoad2->setCurrentIndex(-1);
    hblBaseShpa->addWidget(cbRoad2);

    lbKm = new QLabel(tr("Км:"));
    hblBaseShpa->addWidget(lbKm);
    dsbKm = new QDoubleSpinBox();
    hblBaseShpa->addWidget(dsbKm);

    wShpa->setLayout(hblBaseShpa);
    swBase->addWidget(wShpa);

    vblMain->addWidget(swBase);

    //all
    hblTypes = new QHBoxLayout;

    lbTypeDTP = new QLabel(tr("Вид ДТП:"));
    hblTypes->addWidget(lbTypeDTP);
    cbTypeDTP = new QComboBox;
    cbTypeDTP->addItems(logic::getTypesDTP());
    cbTypeDTP->setCurrentIndex(-1);
    hblTypes->addWidget(cbTypeDTP);

    lbTypeTr = new QLabel(tr("Вид ТС:"));
    hblTypes->addWidget(lbTypeTr);
    cbTypeTr = new QComboBox;
    cbTypeTr->addItems(logic::getTypesTr());
    cbTypeTr->setCurrentIndex(-1);
    hblTypes->addWidget(cbTypeTr);

    pbMakeDiagram = new QPushButton(tr("С&формировать"));
    hblTypes->addWidget(pbMakeDiagram);

    connect(pbMakeDiagram, SIGNAL(clicked()),
            this, SLOT(on_pbMakeDiagram_clicked()));

    vblMain->addLayout(hblTypes);


    //let's create this fucking diagram
    plotAffect = new QwtPlot;
    plotAffect->setTitle(tr("Пострадавших"));
    plotAffect->setCanvasBackground(QColor(Qt::white));

    plotDead = new QwtPlot;
    plotDead->setTitle(tr("Погибших"));
    plotDead->setCanvasBackground(QColor(Qt::white));

    hblPlots = new QHBoxLayout();
    hblPlots->addWidget(plotAffect);
    hblPlots->addWidget(plotDead);
    vblMain->addLayout(hblPlots);

    plotGridAffect = new QwtPlotGrid;
    plotGridAffect->enableXMin(true);
    plotGridAffect->enableYMin(true);
    plotGridAffect->setMajPen(QPen(Qt::black, 0, Qt::DotLine));
    plotGridAffect->setMinPen(QPen(Qt::black, 0, Qt::DotLine));
    plotGridAffect->attach(plotAffect);

    plotGridDead = new QwtPlotGrid;
    plotGridDead->enableXMin(true);
    plotGridDead->enableYMin(true);
    plotGridDead->setMajPen(QPen(Qt::black, 0, Qt::DotLine));
    plotGridDead->setMinPen(QPen(Qt::black, 0, Qt::DotLine));
    plotGridDead->attach(plotDead);

    histogramAffect = new HistogramItem();
    histogramAffect->setColor(Qt::darkCyan);

    histogramDead = new HistogramItem();
    histogramDead->setColor(Qt::darkCyan);


    histogramAffect->attach(plotAffect);
    histogramDead->attach(plotDead);

    setAxisOptions(QwtPlot::yLeft, 0, 31, 5);
    setAxisOptions(QwtPlot::xBottom, 0, 31, 5);

    plotDead->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    plotAffect->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);


    plotAffect->setVisible(true);
    plotDead->setVisible(true);

    //vblMain->addSpacing(0);
    this->setLayout(vblMain);

}

void DiagramAffectDeadDialog::on_chbCrossroadStav_clicked()
{
    if (chbCrossroadStav->isChecked()) {
        lbHouse->setVisible(false);
        leHouse->setVisible(false);
        lbCorps->setVisible(false);
        leCorps->setVisible(false);
        lbStreet2->setVisible(true);
        cbStreet2->setVisible(true);;
    }
    else {
        lbHouse->setVisible(true);
        leHouse->setVisible(true);
        lbCorps->setVisible(true);
        leCorps->setVisible(true);
        lbStreet2->setVisible(false);
        cbStreet2->setVisible(false);
    }
}

void DiagramAffectDeadDialog::on_chbCrossroadShpa_clicked()
{
    if (chbCrossroadShpa->isChecked()) {
        lbKm->setVisible(false);
        dsbKm->setVisible(false);
        lbRoad2->setVisible(true);
        cbRoad2->setVisible(true);
    }
    else {
        lbKm->setVisible(true);
        dsbKm->setVisible(true);
        lbRoad2->setVisible(false);
        cbRoad2->setVisible(false);
    }
}

void DiagramAffectDeadDialog::on_pbMakeDiagram_clicked()
{
    if(deDate->date().isNull()) {
        QMessageBox::warning(this, tr("Неккоректное заполнение формы!"),
                             tr("Вы не указали дату."),
                             QMessageBox::Ok, QMessageBox::Ok);
        //return;
    }
    updateQueryOptions();
    int numValues;
    if(cbPeriod->currentText() == "Месяц") {
        numValues = daysInMonth(deDate->date().year(), deDate->date().month());
        setAxisOptions(QwtPlot::xBottom, 0, numValues, 5);
    }
    else if(cbPeriod->currentText() == "Год") {
        numValues = 12;
        setAxisOptions(QwtPlot::xBottom, 0, numValues, 1);
    }

    //Input data into plotAffect and plotDead
    QwtArray<QwtDoubleInterval> intervals(numValues);
    intervals = qwtIntervals(numValues);
    QwtArray<double> valuesAffect(numValues);
    QwtArray<double> valuesDead(numValues);

    yMax = 0;
    valuesAffect = qwtAffectArray();
    valuesDead = qwtDeadArray();

    int stepSize;
    yMax > 10 ? stepSize = 5 : stepSize = 1;
    setAxisOptions(QwtPlot::yLeft, 0, yMax, stepSize);

    histogramAffect->setData(QwtIntervalData(intervals, valuesAffect));
    histogramAffect->attach(plotAffect);

    histogramDead->setData(QwtIntervalData(intervals,valuesDead));
    histogramDead->attach(plotDead);

    plotDead->replot();
    plotAffect->replot();
}


void DiagramAffectDeadDialog::updateQueryOptions()
{
    queryOptions.clear();
    queryOptionsSQL.clear();

    if(cbLocation->currentIndex() == 0) {
        //Stavropol
        queryOptionsSQL.prepend("FROM `transstav` WHERE ");
        if(cbDistrict->currentIndex() != -1) {
            queryOptions << "`distrid`=\"" +cbDistrict->currentText() +"\"";
        }
        if(cbStreet1->currentIndex() != -1) {
            queryOptions << "`str1id`=\"" +cbStreet1->currentText() +"\" ";
        }
        if(chbCrossroadStav->isChecked()) {
            if(cbStreet2->currentIndex() != -1) {
                queryOptions << "`str2id`=\"" +cbStreet2->currentText() +"\"";
            }
            else {
                if(!leHouse->text().isEmpty()) {
                    queryOptions << "`hnum`=\"" +leHouse->text() +"\"";
                }
                if(!leCorps->text().isEmpty()) {
                    queryOptions << "`corps`=\"" +leCorps->text() +"\"";
                }
            }
        }
    }
    else {
        queryOptionsSQL.append("FROM `transshpa` WHERE ");
        if(cbRoad1->currentIndex() != -1) {
            queryOptions << "`road1id`=\"" +cbRoad1->currentText() +"\"";
        }
        if(chbCrossroadShpa->isChecked()) {
            if(cbRoad2->currentIndex() != -1) {
                queryOptions << "`road2id`\"" +cbRoad2->currentText() +"\"";
            }
        }
        else {
            if(dsbKm->value() != 0) {
                queryOptions << "`km`=\"" +QString::number(dsbKm->value()) +"\"";
            }
        }
    }
    if(cbTypeDTP->currentIndex() != -1) {
        queryOptions << "`typedtpid`=\"" +cbTypeDTP->currentText() +"\"";
    }
    if(cbTypeTr->currentIndex() != -1) {
        queryOptions << "`typetrid`=\"" +cbTypeTr->currentText() +"\"";
    }
}

void DiagramAffectDeadDialog::updateQuerySqlOptions()
{

}


QwtArray<double> DiagramAffectDeadDialog::qwtAffectArray()
{
    int numValues;
    if(cbPeriod->currentText() == "Месяц") {
        numValues = daysInMonth(deDate->date().year(), deDate->date().month());
    }
    else if(cbPeriod->currentText() == "Год") {
        numValues = 12;
    }

    QwtArray<double> array(numValues);
    QSqlQuery query;

    if(cbPeriod->currentText() == "Месяц") {
        query.prepare(QString("SELECT DAYOFMONTH(datedtp),SUM(numaffected) %1 %2 %3 %4 ")
                      .arg(queryOptionsSQL)
                      .arg("YEAR(datedtp)=" +QString::number(deDate->date().year()))
                      .arg(" AND MONTH(datedtp)=" +QString::number(deDate->date().month()))
                      .arg(" GROUP BY 1") );
        if(!query.exec()) {
            qCritical() << "SQL execute ERROR: " +query.lastError().text()
                    +"\nQueryText: " +query.lastQuery();
        }
        else {
            qDebug() << query.lastQuery();
            while(query.next()) {
                qDebug() << query.value(0).toInt() << " " << query.value(1).toInt();
                int day = query.value(0).toInt();
                int value = query.value(1).toInt();
                array[day] = value;
                qDebug() << "||" << QString::number(array[query.value(0).toInt()]);
                if (value > yMax)
                    yMax = value;
            }
        }
    }
    else if(cbPeriod->currentText() == "Год") {
        query.prepare("SELECT  MONTH(datedtp),SUM(numaffected) " +queryOptionsSQL +" YEAR(datedtp)=" +QString::number(deDate->date().year())
                      +" GROUP BY 1" );
        if(!query.exec()) {
            qCritical() << "SQL execute ERROR: " +query.lastError().text()
                    +"\nQueryText: " +query.lastQuery();
        }
        else {
            qDebug() << query.lastQuery();
            while(query.next()) {
                qDebug() << query.value(0).toInt() << " " << query.value(1).toInt();
                int month = query.value(0).toInt();
                int value = query.value(1).toInt();
                array[month] = value;
                if (value > yMax)
                    yMax = value;
            }
        }
    }
    return array;
}


QwtArray<double> DiagramAffectDeadDialog::qwtDeadArray() {
    int numValues;
    if(cbPeriod->currentText() == "Месяц") {
        numValues = daysInMonth(deDate->date().year(), deDate->date().month());
    }
    else if(cbPeriod->currentText() == "Год") {
        numValues = 12;
    }

    QwtArray<double> array(numValues);
    QSqlQuery query;

    if(cbPeriod->currentText() == "Месяц") {
        query.prepare(QString("SELECT  DAYOFMONTH(datedtp),SUM(numdead) %1 %2 %3 %4")
                      .arg(queryOptionsSQL)
                      .arg("YEAR(datedtp)=" +QString::number(deDate->date().year()))
                      .arg("AND MONTH(datedtp)=" +QString::number(deDate->date().month()))
                      .arg("GROUP BY 1") );
        if(!query.exec()) {
            qCritical() << "SQL execute ERROR: " +query.lastError().text()
                    +"\nQueryText: " +query.lastQuery();;
        }
        else {
            qDebug() << query.lastQuery();
            while(query.next()) {
                qDebug() << query.value(0).toInt() << " " << query.value(1).toInt();
                int day = query.value(0).toInt();
                int value = query.value(1).toInt();
                array[day] = value;
                if (value > yMax)
                    yMax = value;
            }
        }
    }
    else if(cbPeriod->currentText() == "Год") {
        numValues = 12;
        query.prepare("SELECT  MONTH(datedtp),SUM(numdead) " +queryOptionsSQL +" YEAR(datedtp)=" +QString::number(deDate->date().year())
                      +" GROUP BY 1" );
        if(!query.exec()) {
            qCritical() << "SQL execute ERROR: " +query.lastError().text()
                    +"\nQueryText: " +query.lastQuery();
        }
        else {
            qDebug() << query.lastQuery();
            while(query.next()) {
                qDebug() << query.value(0).toInt() << " " << query.value(1).toInt();
                int month = query.value(0).toInt();
                int value = query.value(1).toInt();
                array[month] = value;
                if (value > yMax)
                    yMax = value;
            }
        }
    }
    return array;
}


QwtArray<QwtDoubleInterval> DiagramAffectDeadDialog::qwtIntervals(int num)
{
    QwtArray<QwtDoubleInterval> intervalArray(num);
    int i = 0;
    int pos = 0;
    int width = 1;
    while(i < num) {
        intervalArray[i] = QwtDoubleInterval(pos, pos + width);
        pos += width;
        ++i;
    }
    return intervalArray;
}

void DiagramAffectDeadDialog::setAxisOptions(int axisId, int min, int max, int stepSize)
{
    plotAffect->setAxisScale(axisId, min, max, stepSize);
    plotAffect->replot();

    plotDead->setAxisScale(axisId, min, max, stepSize);
    plotDead->replot();
}
